#pragma once

class List;

template <typename T>
class DataItem
{
    friend class List;
public:
    DataItem();
    DataItem(const T& data,DataItem<T>*p_next);

private:
    T value;
    DataItem<T>* next;

};

template<typename T>
DataItem<T>::DataItem()
{
    p_next=NULL;
}

template<typename T>
DataItem<T>::DataItem(const T& data,DataItem<T>*p_next)
{
    thuis->value=data;
    next=p_next;
}


template<typename T>
class List
{
    public:
        List();

        bool insert(const T& data);
        void delete(const T& data);
        bool Find(const T& data);

        bool IsEmpty();
        int Length();

    private:
        DataItem<T>* head;
        DataItem<T>* last;
        int length;

} 

template<typename T>
List<T>::List()
{
    length=0;
    head=new DataItem<T>();
    head->next=NULL;
    last=head;
}

template<typename T>
bool List<T>::insert(const T& data)
{
    DataItem<T>* temp=new DataItem(data,NULL);
    if(!temp)
    {
        return false;
    }

    last->next=temp;
    last=last->next;

    ++length;
}

template<typename T>
void List<T>::delete(const T& data)
{
    DataItem<T>* temp=head->next;
    DataItem<T>* tool;

    while(temp)
    {
        if(data == temp->value)
        {
            tool=temp;
            temp=tool->next;
            delete tool;
            if(tool)
            {
                tool=NULL;
            }
            --length;
        }
    }
}

template<typename T>
bool List<T>::Find(const T& data)
{
    DataItem<T>* temp=head->next;

    bool result=false;
    while(temp)
    {
        if(data == temp->value)
        {
            result=true;
            break;
        }
    }

    return result;
}

template<typename T>
bool List<T>::IsEmpty()
{
    if(length>0)
    {
        return false;
    }
    e;se
    {
        return true;
    }
}

template<typename T>
int List<T>::Length()
{
    return length;
}